package com.rs.game.player;

import java.io.Serializable;

import com.rs.cache.loaders.NPCDefinitions;
import com.rs.game.World;
import com.rs.game.item.Item;
import com.rs.io.OutputStream;
import com.rs.utils.Utils;

public class Appearence implements Serializable {

	private static final long serialVersionUID = 7655608569741626586L;

	private short transformedNpcId;
	private int renderEmote;
	private byte[] look;
	private byte[] colour;
	private boolean male;
	
	private transient byte[] appeareanceData;
	private transient byte[] md5AppeareanceDataHash;
	
	private transient Player player;
	
	public Appearence() {
		male = true;
		transformedNpcId = -1;
		renderEmote = -1;
		resetAppearence();
	}
	
	
	public void setPlayer(Player player) {
		this.player = player;
	}
	
	public void transformIntoNPC(int id) {
		transformedNpcId = (short) id;
		generateAppearenceData();
	}
	
	public void generateAppearenceData() {
		OutputStream stream = new OutputStream();
		int flag = 0;
		if(!male)
			flag |= 0x1;
		if(player.hasDisplayName())
			flag |= 0x2;
		//flag |= 0x4; //the way combat lvl sent
	//	flag |= value << 3 & 0x7; //dunno
	//	flag |= (1 & 0xeb) << 6; //dunno
		stream.writeByte(flag);
		stream.writeByte(-1); // mobi arms titles
		stream.writeByte(player.hasSkull() ? 0 : -1); // pk icon
		stream.writeByte(player.getPrayer().getPrayerHeadIcon()); // prayer icon
		//npc
		if(transformedNpcId >= 0) {
			stream.writeShort(-1); //65535 tells it a npc
			stream.writeShort(transformedNpcId);
			stream.writeByte(0);	
		}else{
			for (int index = 0; index < 4; index++) {
				Item item = player.getEquipment().getItems().get(index);
				if (item == null)
					stream.writeByte(0);
				else
					stream.writeShort(32768 + item.getEquipId());
			}
			Item item = player.getEquipment().getItems().get(Equipment.SLOT_CHEST);
			stream.writeShort(item == null ? 0x100 + look[2] : 32768 + item.getEquipId());
			item = player.getEquipment().getItems().get(Equipment.SLOT_SHIELD);
			if(item == null)
				stream.writeByte(0);
			else
				stream.writeShort(32768 + item.getEquipId());
			item = player.getEquipment().getItems().get(Equipment.SLOT_CHEST);
			if(item == null || !Equipment.isFullBody(item))
				stream.writeShort(0x100 + look[3]);
			else
				stream.writeByte(0);
			item = player.getEquipment().getItems().get(Equipment.SLOT_LEGS);
			stream.writeShort(item == null ? 0x100 + look[5] : 32768 + item.getEquipId());
			item = player.getEquipment().getItems().get(Equipment.SLOT_HAT);
			if(item == null || (!Equipment.isFullMask(item) && !Equipment.isFullHat(item)))
				stream.writeShort(0x100 + look[0]);
			else
				stream.writeByte(0);
			item = player.getEquipment().getItems().get(Equipment.SLOT_HANDS);
			stream.writeShort(item == null ? 0x100 + look[4] : 32768 + item.getEquipId());
			item = player.getEquipment().getItems().get(Equipment.SLOT_FEET);
			stream.writeShort(item == null ? 0x100 + look[6] : 32768 + item.getEquipId());
			item = player.getEquipment().getItems().get(Equipment.SLOT_HAT);
			if(item == null || !Equipment.isFullMask(item))
				stream.writeShort(0x100 + look[1]);
			else
				stream.writeByte(0);	
		}
		for (int index = 0; index < 5; index++)
			stream.writeByte(colour[index]);
		stream.writeShort(getRenderEmote()); 
		stream.writeString(player.getDisplayName());
		if(player.hasDisplayName())
			stream.writeString(player.getUsername());
		boolean pvpArea = World.isPvpArea(player);
		stream.writeByte(pvpArea ? player.getSkills().getCombatLevel() : player.getSkills().getCombatLevelWithSummoning());
		stream.writeByte(pvpArea ? player.getSkills().getCombatLevelWithSummoning() : 0);
		stream.writeByte(-1); //higher level acc name appears in front :P
		stream.writeShort(0); // 1 for send all emotes 1by1 used for
		//done separated for safe because of sycrozination
		byte[] appeareanceData = new byte[stream.getOffset()];
		System.arraycopy(stream.getBuffer(), 0, appeareanceData, 0, appeareanceData.length);
		byte[] md5Hash = Utils.encryptUsingMD5(appeareanceData);
		this.appeareanceData = appeareanceData;
		md5AppeareanceDataHash = md5Hash;
	}
	
	public int getSize() {
		if(transformedNpcId >= 0)
			return NPCDefinitions.getNPCDefinitions(transformedNpcId).size;
		return 1;
	}
	
	public void setRenderEmote(int id) {
		this.renderEmote = id;
		generateAppearenceData();
	}
	public int getRenderEmote() {
		if(renderEmote >= 0)
			return renderEmote;
		if(transformedNpcId >= 0)
			return NPCDefinitions.getNPCDefinitions(transformedNpcId).renderEmote;
		return player.getEquipment().getWeaponRenderEmote();
	}
	public void resetAppearence() {
		look = new byte[7];
		colour = new byte[5];
		look[0] = 3; // Hair
		look[1] = 14; // Beard
		look[2] = 18; // Torso
		look[3] = 26; // Arms
		look[4] = 34; // Bracelets
		look[5] = 38; // Legs
		look[6] = 42; // Shoes~
		
		colour[2] = 16;
		colour[1] = 16;
		colour[0] = 3;
		
	}
	
	public byte[] getAppeareanceData() {
		return appeareanceData;
	}
	public byte[] getMD5AppeareanceDataHash() {
		return md5AppeareanceDataHash;
	}
	
}
